﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Bowling;

namespace Bowling.Game
{
    /// <summary>
    /// 볼링 게임 스코어 처리에 관련된 클래스입니다.
    /// </summary>
    /// <remarks>
    /// 작성자: 권혁준
    /// </remarks>
    public class GamePlay
    {
        //10번째 프레임의 보너스 던지기 상수값
        public const int BONUS_TRUE = 3;

        public int pins;

        //프레임당 맞춘 핀 개수
        public int score1;
        public int score2;

        //프레임에서 던지기 회차
        public int throwCnt;

        public int frameNo;
        
        //10번 프레임에서 보너스 유무 확인 변수
        public int bonusCnt;

        public GameInfo gameInfo;
        public GameScore gameScore;

        public GamePlay(GameInfo gameInfo)
        {
            pins = 0;
            score1 = 0;
            score2 = 0;

            throwCnt = 1;
            frameNo = 1;
            bonusCnt = 0;

            gameScore = new GameScore();

            this.gameInfo = gameInfo;
        }

        /// <summary>
        /// 롤 버튼 이벤트 메소드입니다.
        /// 1~9번 프레임과 10번 프레임을 구분하여 스코어를 처리합니다.
        /// </summary>
        /// <param name="pins">입력 핀값</param>
        /// <returns>
        /// GameScore를 반환합니다. 
        /// GameScore 클래스는 프레임당 점수와 핀 숫자를 표시하기 위한 값들을 포함합니다.
        /// </returns>
        /// <remarks>
        /// 작성자: 권혁준
        /// </remarks>
        public GameScore Roll(int pins)
        {
            //스코어 표시를 기다리고 있는 프레임들을 확인하며, 던지기를 할때 마다 대기값을 줄여줍니다.
            foreach (WaitFrameScore wfs in gameInfo.waitFrameList)
            {
                if (wfs.waitNo != 0)
                {
                    wfs.waitScore += pins;
                    wfs.waitNo--;
                }
            }

            //1~9번 프레임
            if (frameNo < 10)
            {
                //프레임에서 롤 첫 번째
                if (throwCnt == 1)
                {
                    score1 = pins;

                    gameScore.SetPins(gameInfo, frameNo, throwCnt, score1);
                    throwCnt = 2;

                    if (score1 == 10)
                    {
                        //스트라이크
                        gameInfo.Strike(frameNo, score1);
                        frameNo++;
                        throwCnt = 1;
                        score1 = 0;
                    }
                }
                else//프레임에서 롤 두 번째
                {
                    score2 = pins;

                    //스페어
                    if ((score1 + score2) == 10)
                    {
                        gameInfo.Spare(frameNo, score1 + score2);
                    }
                    else
                    {
                        gameInfo.NextFrame(frameNo, score1 + score2);
                    }

                    score1 = 0;
                    gameScore.SetPins(gameInfo, frameNo, throwCnt, score2);
                    throwCnt = 1;
                    frameNo++;
                }

                gameScore.SetFrame(gameInfo, frameNo - 1, score1 + score2);
                score2 = 0;
            }
            //10번 프레임
            else if (frameNo == 10)
            {
                if (throwCnt == 1)
                {
                    score1 = pins;
                    gameScore.SetPins(gameInfo, frameNo, throwCnt, score1);
                    throwCnt = 2;

                    //스트라이크
                    if (pins == 10)
                    {
                        gameInfo.Strike(frameNo, score1);
                        score1 = 0;
                        bonusCnt = BONUS_TRUE;
                    }
                }
                //두 번째 던지기
                else if (throwCnt == 2)
                {
                    score2 = pins;

                    //스페어
                    if ((score1 + pins) == 10 & gameInfo.frameState[frameNo-1] != 2)
                    {
                        //프레임 스코어 셋
                        gameInfo.Spare(frameNo, score1 + score2);
                        //보너스 프레임 셋
                        bonusCnt = BONUS_TRUE;
                        score1 = 0;
                    }
                    else if (pins == 10 & gameInfo.frameState[frameNo - 1] == 2)
                    {
                        //마지막 프레임 두 번째 스트라이크
                        gameInfo.Strike(frameNo, score2);
                        
                        bonusCnt = BONUS_TRUE;
                    }
                    else
                    {
                        gameInfo.NextFrame(frameNo, score1 + score2);
                    }

                    gameScore.SetPins(gameInfo, frameNo, throwCnt, score2);
                    score2 = 0;
                    throwCnt = 1;
                    frameNo++;

                }
                gameScore.SetFrame(gameInfo, frameNo - 1, score1 + score2);
                
            }

            //보너스 프레임
            else if (bonusCnt == 3 & frameNo == 11)
            {
                //보너스 스코어 셋
                int score3 = pins;

                //보너스 프레임 스트라이크
                if (pins == 10)
                {
                    gameInfo.Strike(frameNo - 1, 10 + score2 + score3);
                }
                //보너스 프레임 스페어
                else if (score3 + score2 == 10 & gameInfo.frameState[frameNo-2] != 1)
                {
                    gameInfo.Spare(frameNo - 1, 10 + score2 + score3);
                }
                else
                {
                    gameInfo.NextFrame(frameNo - 1, 10 + score3);
                }
                gameScore.SetPins(gameInfo, frameNo - 1, bonusCnt, score3);
                gameScore.SetFrame(gameInfo, frameNo - 1, score1 + score2 + score3);
                
                bonusCnt = 0;
            }
            //프레임 종료
            else
            {
                gameScore.isEndGame = true;
                return gameScore;

            }

            return gameScore;
        }
    }
}
